﻿using SqlSugar;
using System.Linq.Expressions;

namespace Luka;

/// <summary>
/// 基础仓储层接口
/// </summary>
/// <typeparam name="T">数据类型</typeparam>
public partial interface IBaseRepository<TEntity> : IScoped where TEntity : class, new()
{
    #region 获取连接对象

    /// <summary>
    /// 连接对象
    /// </summary>
    ISqlSugarClient Session();

    /// <summary>
    /// 连接对象(查询)
    /// </summary>
    ISugarQueryable<TEntity> Queryable();

    /// <summary>
    /// 操作对象（查询多库）
    /// </summary>
    ISugarQueryable<TEntity> QueryableAttr();

    /// <summary>
    /// 连接对象(删除)
    /// </summary>
    IDeleteable<TEntity> Deleteable();

    /// <summary>
    /// 连接对象(修改)
    /// </summary>
    IUpdateable<TEntity> Updateable();

    #endregion 获取连接对象

    #region 普通操作方法

    #region 基本操作方法

    /// <summary>
    /// 根据主键判断是否存在
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    bool IsAny(object id);

    /// <summary>
    /// 根据表达式判断是否存在
    /// </summary>
    /// <param name="expression">表达式</param>
    /// <returns></returns>
    bool IsAny(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 根据主键查询单个
    /// </summary>
    /// <param name="id">主键id</param>
    /// <returns></returns>
    TEntity GetSingle(object id);

    /// <summary>
    /// 根据表达式查询单个
    /// </summary>
    /// <param name="expression">表达式</param>
    /// <returns></returns>
    TEntity GetSingle(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 查询详情第一条
    /// </summary>
    /// <param name="expression">表达书树条件</param>
    /// <returns></returns>
    TEntity GetFirst(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 查询列表
    /// </summary>
    /// <returns></returns>
    List<TEntity> GetList();

    /// <summary>
    /// 查询列表
    /// </summary>
    /// <param name="expression">表达式</param>
    /// <returns></returns>
    List<TEntity> GetList(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 分页
    /// </summary>
    /// <param name="input">公共分页参数</param>
    /// <returns></returns>
    PagedOutput<TEntity> GetPagedList(PagedInput input);

    /// <summary>
    /// 分页
    /// </summary>
    /// <param name="input">公共分页参数</param>
    /// <param name="expression">表达式</param>
    /// <returns></returns>
    PagedOutput<TEntity> GetPagedList(PagedInput input, Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 获取数量
    /// </summary>
    /// <returns></returns>
    int GetCount();

    /// <summary>
    /// 获取数量
    /// </summary>
    /// <returns></returns>
    int GetCount(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 保存单个
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    int Save(TEntity model);

    /// <summary>
    /// 保存单个(返回主键id)
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    int SaveRetundId(TEntity model);

    /// <summary>
    /// 保存单个(返回实体对象)
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    TEntity SaveRetundEntity(TEntity model);

    /// <summary>
    /// 保存单个（返回雪花id）
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    long SaveBySnowflakeId(TEntity model);

    /// <summary>
    /// 保存集合（返回雪花id）
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    List<long> SaveAllBySnowflakeId(List<TEntity> models);

    /// <summary>
    /// 保存集合
    /// </summary>
    /// <param name="input">输入值</param>
    /// <returns></returns>
    int SaveAll(List<TEntity> models);

    /// <summary>
    /// 修改单个
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    int Update(TEntity model);

    /// <summary>
    /// 修改单个(添加条件)
    /// </summary>
    /// <param name="model">输入值</param>
    /// <param name="expression">表达式</param>
    /// <returns></returns>
    int Update(TEntity model, Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 修改集合
    /// </summary>
    /// <param name="models">输入集合</param>
    /// <returns></returns>
    int Update(List<TEntity> models);

    /// <summary>
    /// 修改集合(只更新某列)
    /// </summary>
    /// <param name="models">输入集合</param>
    /// <param name="columns"></param>
    /// <returns></returns>
    int Update(List<TEntity> models, Expression<Func<TEntity, object>> columns);

    /// <summary>
    /// 插入或更新集合
    /// </summary>
    /// <param name="models">输入值</param>
    /// <returns></returns>
    int SaveOrUpdateAll(List<TEntity> models);

    /// <summary>
    /// 根据主键删除
    /// </summary>
    /// <param name="id">主键id</param>
    /// <returns></returns>
    int UpdateIgnoreColumns(object id);

    /// <summary>
    /// 根据主键删除多个
    /// </summary>
    /// <param name="ids">id字符串，以逗号隔开</param>
    /// <returns></returns>
    int Update(int[] ids);

    /// <summary>
    /// 根据表达式删除
    /// </summary>
    /// <param name="expression">表达式</param>
    /// <returns></returns>
    int Update(Expression<Func<TEntity, bool>> expression);

    #endregion 基本操作方法

    #region sql语句操作方法

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <returns></returns>
    TEntity GetSingleBySql(string sql);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">单个参数</param>
    /// <returns></returns>
    TEntity GetSingleBySql(string sql, SugarParameter[] parameters);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">多个参数</param>
    /// <returns></returns>
    TEntity GetSingleBySql(string sql, List<SugarParameter> parameters);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <returns></returns>
    List<TEntity> GetListBySql(string sql);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">单个参数</param>
    /// <returns></returns>
    List<TEntity> GetListBySql(string sql, SugarParameter[] parameters);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">多个参数</param>
    /// <returns></returns>
    List<TEntity> GetListBySql(string sql, List<SugarParameter> parameters);

    /// <summary>
    /// 增删改
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <returns></returns>
    int ExecuteCommand(string sql);

    /// <summary>
    /// 增删改
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">单个参数</param>
    /// <returns></returns>
    int ExecuteCommand(string sql, SugarParameter[] parameters);

    /// <summary>
    /// 增删改
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">多个参数</param>
    /// <returns></returns>
    int ExecuteCommand(string sql, List<SugarParameter> parameters);

    /// <summary>
    /// 查询字符串
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <returns></returns>
    string GetStringBySql(string sql);

    #endregion sql语句操作方法

    #endregion 普通操作方法

    #region 异步操作方法

    #region 基本操作方法

    /// <summary>
    /// 根据主键判断是否存在
    /// </summary>
    /// <param name="id">主键id</param>
    /// <returns></returns>
    Task<bool> IsAnyAsync(object id);

    /// <summary>
    /// 查询详情
    /// </summary>
    /// <param name="id">主键id</param>
    /// <returns></returns>
    Task<TEntity> GetSingleAsync(object id);

    /// <summary>
    /// 查询详情第一条
    /// </summary>
    /// <param name="expression">表达书树条件</param>
    /// <returns></returns>
    Task<TEntity> GetFirstAsync(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 查询详情
    /// </summary>
    /// <param name="expression">表达书树条件</param>
    /// <returns></returns>
    Task<TEntity> GetSingleAsync(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 查询集合
    /// </summary>
    Task<List<TEntity>> GetListAsync();

    /// <summary>
    /// 查询集合
    /// </summary>
    /// <param name="expression">表达书树条件</param>
    /// <returns></returns>
    Task<List<TEntity>> GetListAsync(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 分页
    /// </summary>
    /// <param name="input">公共分页参数</param>
    /// <returns></returns>
    Task<PagedOutput<TEntity>> GetPagedListAsync(PagedInput input);

    /// <summary>
    /// 分页
    /// </summary>
    /// <param name="input">公共分页参数</param>
    /// <param name="expression">表达式</param>
    /// <returns></returns>
    Task<PagedOutput<TEntity>> GetPagedListAsync(PagedInput input, Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 获取数量
    /// </summary>
    /// <returns></returns>
    Task<int> GetCountAsync();

    /// <summary>
    /// 获取数量
    /// </summary>
    /// <returns></returns>
    Task<int> GetCountAsync(Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 保存单个（返回雪花id）
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    Task<long> SaveBySnowflakeIdAsync(TEntity model);

    /// <summary>
    /// 保存集合（返回雪花id）
    /// </summary>
    /// <param name="model">输入集合</param>
    /// <returns></returns>
    Task<List<long>> SaveAllBySnowflakeIdAsync(List<TEntity> models);

    /// <summary>
    /// 添加
    /// </summary>
    /// <returns></returns>
    Task<int> SaveAsync(TEntity model);

    /// <summary>
    /// 保存单个(返回主键id)
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    Task<int> SaveRetundIdAsync(TEntity model);

    /// <summary>
    /// 保存单个(返回实体对象)
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    Task<TEntity> SaveRetundEntityAsync(TEntity model);

    /// <summary>
    /// 添加
    /// </summary>
    /// <returns></returns>
    Task<int> SaveAllAsync(List<TEntity> models);

    /// <summary>
    /// 修改
    /// </summary>
    /// <returns></returns>
    Task<int> UpdateAsync(TEntity model);

    /// <summary>
    /// 修改单个(添加条件)
    /// </summary>
    /// <param name="model">输入值</param>
    /// <returns></returns>
    Task<int> UpdateAsync(TEntity model, Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 修改
    /// </summary>
    /// <param name="models">输入集合</param>
    /// <returns></returns>
    Task<int> UpdateAllAsync(List<TEntity> models);

    /// <summary>
    /// 修改集合
    /// </summary>
    /// <param name="models">输入集合</param>
    /// <returns></returns>
    Task<int> UpdateAllAsync(List<TEntity> models, Expression<Func<TEntity, bool>> expression);

    /// <summary>
    /// 修改或保存
    /// </summary>
    /// <returns></returns>
    Task<int> SaveOrUpdateAllAsync(List<TEntity> models);

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="id">主键id</param>
    /// <returns></returns>
    Task<int> DeleteAsync(object id);

    /// <summary>
    /// 根据主键删除多个
    /// </summary>
    /// <param name="ids">id集合</param>
    /// <returns></returns>
    Task<int> DeleteByIdsAsync(int[] ids);

    /// <summary>
    /// 删除
    /// </summary>
    /// <param name="expression">表达书树条件</param>
    /// <param name="isFeign">是否软删除,默认true</param>
    /// <returns></returns>
    Task<int> DeleteAsync(Expression<Func<TEntity, bool>> expression);

    #endregion 基本操作方法

    #region sql语句操作方法

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <returns></returns>
    Task<TEntity> GetSingleBySqlAsync(string sql);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">单个参数</param>
    /// <returns></returns>
    Task<TEntity> GetSingleBySqlAsync(string sql, SugarParameter[] parameters);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">多个参数</param>
    /// <returns></returns>
    Task<TEntity> GetSingleBySqlAsync(string sql, List<SugarParameter> parameters);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <returns></returns>
    Task<List<TEntity>> GetListBySqlAsync(string sql);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">单个参数</param>
    /// <returns></returns>
    Task<List<TEntity>> GetListBySqlAsync(string sql, SugarParameter[] parameters);

    /// <summary>
    /// sql语句查询单个
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">多个参数</param>
    /// <returns></returns>
    Task<List<TEntity>> GetListBySqlAsync(string sql, List<SugarParameter> parameters);

    /// <summary>
    /// 增删改
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <returns></returns>
    Task<int> ExecuteCommandAsync(string sql);

    /// <summary>
    /// 增删改
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">单个参数</param>
    /// <returns></returns>
    Task<int> ExecuteCommandAsync(string sql, SugarParameter[] parameters);

    /// <summary>
    /// 增删改
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <param name="parameters">多个参数</param>
    /// <returns></returns>
    Task<int> ExecuteCommandAsync(string sql, List<SugarParameter> parameters);

    /// <summary>
    /// 查询字符串
    /// </summary>
    /// <param name="sql">sql语句</param>
    /// <returns></returns>
    Task<string> GetStringBySqlAsync(string sql);

    #endregion sql语句操作方法

    #endregion 异步操作方法
}